package com.cal.utms.dao.maintenance;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.cal.utms.entity.Customer;
import com.cal.utms.entity.CustomerBankAccount;
import com.cal.utms.entity.CustomerCodeSerial;
import com.cal.utms.entity.CustomerContactPerson;
import com.cal.utms.entity.CustomerEmail;
import com.cal.utms.entity.CustomerJointAppicant;
import com.cal.utms.logAudit.AuditLogInterceptor;
import com.cal.utms.util.HibernateUtil;

public class CustomerDaoImpl implements CustomerDao {

	@SuppressWarnings("unchecked")
	public List<Customer> getCustomerList() {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<Customer> customers = new ArrayList<Customer>();
		int pageNumber = 1;
		int pageSize = 10;
		try {
			tx = session.beginTransaction();
			customers = session.createQuery("FROM Customer c").list();
			tx.commit();
			// setFirstResult((pageNumber - 1) *
			// pageSize).setMaxResults(pageSize)
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return customers;
	}

	public Customer getCustomerById(int customer_id) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction transaction = null;
		Customer customer = null;
		try {
			transaction = session.beginTransaction();
			customer = (Customer) session.get(Customer.class, customer_id);
			transaction.commit();
		} catch (HibernateException e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
		} finally {
			session.close();
		}
		return customer;
	}

	@SuppressWarnings("unchecked")
	public List<CustomerBankAccount> getBankAccountByCustomerId(int id) {

		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<CustomerBankAccount> customerBankAccounts = new ArrayList<CustomerBankAccount>();

		try {
			tx = session.beginTransaction();
			customerBankAccounts = session.createQuery("FROM CustomerBankAccount c where c.customer.id =:cusId").setParameter("cusId", id).list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return customerBankAccounts;
	}

	@Override
	public Object saveCustomer(Customer customer) {
		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession(interceptor);
		interceptor.setSession(session);
		Transaction tx = null;
		Object object = null;
		try {
			tx = session.beginTransaction();
			object = session.save(customer);
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return object;
	}

	@Override
	public CustomerCodeSerial getCustomerCode(String cus_type, String cus_residential, String cus_first_let_of_name) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		Object obj = null;
		CustomerCodeSerial codeSerial = null;
		try {
			tx = session.beginTransaction();
			long count = ((Number) session
					.createQuery("select count(*) from CustomerCodeSerial C where C.customerType=:cusType and C.residential=:residential and C.firstLetOfName=:name")
					.setParameter("cusType", cus_type).setParameter("residential", cus_residential).setParameter("name", cus_first_let_of_name).uniqueResult()).longValue();

			tx.commit();
			if (count == 0) {
				tx = session.beginTransaction();
				CustomerCodeSerial customerCodeSerial = new CustomerCodeSerial();
				customerCodeSerial.setCustomerType(cus_type);
				customerCodeSerial.setResidential(cus_residential);
				customerCodeSerial.setFirstLetOfName(cus_first_let_of_name);
				customerCodeSerial.setSerial(1);
				obj = session.save(customerCodeSerial);
				tx.commit();
				if (obj instanceof Integer) {
					int id = (Integer) obj;
					codeSerial = (CustomerCodeSerial) session.get(CustomerCodeSerial.class, id);
				}
			} else {
				tx = session.beginTransaction();
				obj = session
						.createQuery("Update CustomerCodeSerial C set C.serial=C.serial+1 where C.customerType=:cusType and C.residential=:residential and C.firstLetOfName=:name")
						.setParameter("cusType", cus_type).setParameter("residential", cus_residential).setParameter("name", cus_first_let_of_name).executeUpdate();

				codeSerial = (CustomerCodeSerial) session
						.createQuery("from CustomerCodeSerial C where C.customerType=:cusType and C.residential=:residential and C.firstLetOfName=:name")
						.setParameter("cusType", cus_type).setParameter("residential", cus_residential).setParameter("name", cus_first_let_of_name).uniqueResult();
				tx.commit();

			}
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return codeSerial;
	}

	@Override
	public short saveCustomerEmail(List<CustomerEmail> customerEmails) {

		return 0;
	}

	public Object saveCustomer(Customer customer, List<CustomerEmail> customerEmails, List<CustomerBankAccount> customerBankAccounts,
			List<CustomerContactPerson> customerContactPersons, List<CustomerJointAppicant> customerJointAppicants) {

		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession(interceptor);
		interceptor.setSession(session);
		Transaction tx = null;
		Object object = null;
		try {
			tx = session.beginTransaction();
			object = session.save(customer);
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return object;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<CustomerEmail> getEmailByCustomerId(int id) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<CustomerEmail> customerEmails = new ArrayList<CustomerEmail>();
		try {
			tx = session.beginTransaction();
			customerEmails = session.createQuery("FROM CustomerEmail c where c.customer.id =:cusId").setParameter("cusId", id).list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return customerEmails;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<CustomerJointAppicant> getAppicntByCustomerId(int customer_id) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<CustomerJointAppicant> jointAppicants = new ArrayList<CustomerJointAppicant>();
		try {
			tx = session.beginTransaction();
			jointAppicants = session.createQuery("FROM CustomerJointAppicant c where c.customer.id =:cusId").setParameter("cusId", customer_id).list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return jointAppicants;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<CustomerContactPerson> getContactPersonByCusId(int customer_id) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<CustomerContactPerson> contactPersons = new ArrayList<CustomerContactPerson>();
		try {
			tx = session.beginTransaction();
			contactPersons = session.createQuery("FROM CustomerContactPerson c where c.customer.id =:cusId").setParameter("cusId", customer_id).list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return contactPersons;
	}

	@Override
	public Object updateCustomer(Customer customer, List<CustomerBankAccount> customerBankAccounts) {
		Object obj = 0;
		AuditLogInterceptor interceptor = new AuditLogInterceptor();
		Session session = HibernateUtil.getSession().openSession(interceptor);
		interceptor.setSession(session);
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			long count = ((Number) session.createQuery("select count(*) from CustomerEmail E where E.customer.id=:cus_id").setParameter("cus_id", customer.getId()).uniqueResult())
					.longValue();
			if (count > 0) {
				session.createQuery("DELETE FROM CustomerEmail E where E.customer.id=:cus_id").setParameter("cus_id", customer.getId()).executeUpdate();
			}

			long count_c = ((Number) session.createQuery("select count(*) from CustomerContactPerson C where C.customer.id=:cus_id").setParameter("cus_id", customer.getId())
					.uniqueResult()).longValue();
			if (count_c > 0) {
				session.createQuery("DELETE FROM CustomerContactPerson C where C.customer.id=:cus_id").setParameter("cus_id", customer.getId()).executeUpdate();
			}

			long count_j = ((Number) session.createQuery("select count(*) from CustomerJointAppicant J where J.customer.id=:cus_id").setParameter("cus_id", customer.getId())
					.uniqueResult()).longValue();
			if (count_j > 0) {
				session.createQuery("DELETE FROM CustomerJointAppicant J where J.customer.id=:cus_id").setParameter("cus_id", customer.getId()).executeUpdate();
			}

			for (CustomerBankAccount customerBankAccount : customerBankAccounts) {
				session.merge(customerBankAccount);
			}
			obj = session.merge(customer);
			tx.commit();
		} catch (Exception ex) {
			ex.printStackTrace();
			if (tx != null)
				tx.rollback();
			ex.printStackTrace();
		} finally {
			session.close();
		}
		return obj;
	}

	@Override
	public CustomerBankAccount getAccountById(int accountId) {
		Session session = HibernateUtil.getSession().openSession();
		Transaction transaction = null;
		CustomerBankAccount account = null;
		try {
			transaction = session.beginTransaction();
			account = (CustomerBankAccount) session.get(CustomerBankAccount.class, accountId);
			transaction.commit();
		} catch (HibernateException e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
		} finally {
			session.close();
		}
		return account;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Customer> getCustomers(String code, String name) {

		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<Customer> customers = new ArrayList<Customer>();
		try {
			tx = session.beginTransaction();
			customers = session.createQuery("FROM Customer C where (:customercode = '%' or upper(C.code) like :customercode)")
					.setParameter("customercode", (code == null) ? "%" : "%" + code.toUpperCase() + "%").list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return customers;
	}

	public Customer getCustomerByNIC(String nicPassport, String accountType) {

		Session session = HibernateUtil.getSession().openSession();
		Transaction transaction = null;
		Customer customer = null;
		try {
			transaction = session.beginTransaction();
			customer = (Customer) session.createQuery("from Customer C where C.nicPassport=:nic and C.accountType=:acType").setParameter("nic", nicPassport)
					.setParameter("acType", accountType).uniqueResult();
			transaction.commit();
		} catch (HibernateException e) {
			if (transaction != null) {
				transaction.rollback();
			}
			e.printStackTrace();
		} finally {
			session.close();
		}
		return customer;

	}

	@SuppressWarnings("unchecked")
	public List<Customer> getJointCustomerByNIC(String nic, String string) {

		Session session = HibernateUtil.getSession().openSession();
		Transaction tx = null;
		List<Customer> customers = new ArrayList<Customer>();
		try {
			tx = session.beginTransaction();
			customers = session.createQuery("from Customer C where C.nicPassport=:nic and C.accountType=:acType").setParameter("nic", nic).setParameter("acType", string).list();
			tx.commit();
		} catch (HibernateException e) {
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		return customers;
	}
}
